### -*- python -*-
# Copyright (C) 2003, Charles Wang.
# Author:  Charles Wang <charles@linux.net.cn>
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANT; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public LIcense for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, 59 Temple
# Place - Suite 330, Boston, MA 02111-1307, USA.

import os
import os.path
import sys
import string
import types

### Build Argments Help
Help("""
usage: scons [ARGUMENTS] [TARGETS] ...
  specdir=specdir           Specify the specification directory. The default
                            value is 'spec'.
  debug=...                 Specify the ':' separated debug flags.
  buildpkg=[1|0]            Enter package build mode.

Targets:
  allisos                   Build all required distribution iso files.
                            This is the default target too.
  mktests                   Build the test version of MagicBooter in mbtest.
Some other useful targets:
  result/miinitrd
  result/mbboot
  result/mbboot.dbg
  result/pkgarr.py
  result/initrd.dbg.gz
  tmp/root.initrd.tar.gz

Possible debug flags:
  nomnttgt                  Do not mount/umount target partitions.
  nobootloader              Do not install bootloader.
  start.step.N              Start from the specified step. (e.g. start.step.5)
""")

### Command line and Config
#get specdir
specdir = ARGUMENTS.get('specdir', 'spec')
if specdir != '':
    sys.path.insert(0, specdir)
sys.path.insert(0, 'scripts')

import mi_config
mi_config.specdir = specdir
mi_config.sifile = os.path.join(specdir, 'specinfo.py')

if mi_config.develmode:
    mi_config.buildpkg = int(ARGUMENTS.get('buildpkg', '0'))
else:
    mi_config.buildpkg = 0

#check rpmtype
if mi_config.pkgtype != 'rpm':
    print "Only rpm is supported in pkgtype."
    sys.exit(1)

#get pkgdirs
for pd in mi_config.pkgdirs.split(':'):
    if not os.path.isdir(pd):
        print "%s is not a directory" % pd
        sys.exit(1)

#check cross compile
if mi_config.develmode and \
        not os.path.exists(mi_config.cross_compile + 'gcc'):
    print "%s is not exists, your give me a wrong uclibcpath." % \
          mi_config.cross_compile + 'gcc'
    sys.exit(1)

#get debug option
debugopts = ARGUMENTS.get('debug', None)
if debugopts:
    debugopts = string.split(debugopts, ':')
else:
    debugopts = []
mi_config.debugopts = debugopts

### Base Environment
env = Environment()
for k in mi_config.__dict__:
    if k[:2] != '__' and type(mi_config.__dict__[k]) \
       in (types.BooleanType, types.IntType, types.StringType):
        env[k] = mi_config.__dict__[k]

### Scon Utils
def depInstall(env, alias, destdir, files):
    env.Alias(target=alias, source=env.Install(destdir, files))

def depInstallAs(env, alias, destfile, file):
    env.Alias(target=alias, source=env.InstallAs(destfile, file))

def depPyModule(env, alias, dir, sofile, cfiles):
    sopath = os.path.join(mi_config.destdir, mi_config.pythondir, 'site-packages', sofile)
    env.Command(sopath, ['setup.py'] + cfiles,
                ['cd %s; %s setup.py install --prefix=%s/usr' % \
                 (dir, mi_config.pythonbin, mi_config.destdir)])
    env.Alias(alias, sopath)
    #env.Depends(alias, sopath)

# python compiler
def pycompiler(source, target, env):
    import py_compile
    for src in source:
        py_compile.compile(str(src))
pycbuilder = Builder(action=pycompiler)
env['BUILDERS']['PYCBuilder'] = pycbuilder

def DirValue(dir_or_list, env=env):
    def file_stat(arg, dirname, namelist):
        namelist.sort()
        for name in namelist:
            fullname = os.path.join(dirname, name)
            lst = os.lstat(fullname)
            arg.append((fullname, lst.st_size, lst.st_mtime))
            #arg.append((fullname, lst.st_mode, lst.st_dev,
            #            lst.st_uid, lst.st_gid, lst.st_size, lst.st_mtime))
    if type(dir_or_list) is types.ListType:
        dir_list = dir_or_list
    else:
        dir_list = [dir_or_list]
    dir_value = []
    for dir in dir_list:
        os.path.walk(dir, file_stat, dir_value)
    return env.Value(dir_value)

### Scon Maker
import PkgMaker

class MbPkgMaker(PkgMaker.CrossPkgMaker):
    source_prefix = '#bindir/src'
    build_root = mi_config.mbdevrootdir
    install_prefix = mi_config.mbdevrootdir
    CROSS_COMPILE = mi_config.cross_compile
    ARCH = 'i686-linux-uclibc'
    CC_EXTRA = '-I$mbdevrootdir/include -L$mbdevrootdir/lib'
    CPPDEFINES = { '_GNU_SOURCE' : '1',
                  '_LARGEFILE64_SOURCE' : '1'
                   }
    if mi_config.useudev:
        CPPDEFINES['USE_UDEV'] = '1'
    CFLAGS = '-Wall -g -Os -Wno-parentheses -Winline'
    CPPPATH = ['$mbdevrootdir/include']
    LIBPATH = ['$mbdevrootdir/lib']

class MiPkgMaker(PkgMaker.BinPkgMaker):
    source_prefix = '#bindir/src'
    build_root = mi_config.devrootdir
    pack_prefix = '#bindir'

### Export
Export('env')
Export('mi_config')
Export('depInstall', 'depInstallAs', 'depPyModule')
Export('DirValue')
Export('MbPkgMaker', 'MiPkgMaker', 'PkgMaker')

### SConscript
if mi_config.buildpkg:
    SConscript('buildpkg/SConscript')
else:
    SConscript('SConstruct-mb')
    SConscript('SConstruct-mi')
